Skip to content

Conversation

@renezurbruegg
Copy link
Collaborator

@renezurbruegg renezurbruegg commented Aug 28, 2025

Description

This PR introduces MultiMeshRayCaster and MultiMeshRayCasterCamera, an extension of the default RayCaster with the following enhancements:

  1. Raycasting against multiple target types : Supports primitive shapes (spheres, cubes, …) as well as arbitrary meshes.
  2. Dynamic mesh tracking : Keeps track of specified meshes, enabling raycasting against moving parts (e.g., robot links, articulated bodies, or dynamic obstacles).
  3. Memory-efficient caching : Avoids redundant memory usage by caching and reusing duplicate meshes.

This is joint work with @pascal-roth and @Mayankm96.

The default RayCaster was limited to static environments and required manual handling of moving meshes, which restricted its use for robotics scenarios where robots or obstacles move dynamically.

MultiMeshRayCaster addresses these limitations by and now supports raycasting against robot parts and other moving entities.


Usage

For a quick demo, run:

python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type <allegro_hand|anymal_d|multi>
demo image

Drop-in replacement

Example change to migrate from RayCasterCfg to MultiMeshRayCasterCfg:

- ray_caster_cfg = RayCasterCfg(
+ ray_caster_cfg = MultiMeshRayCasterCfg(
      prim_path="{ENV_REGEX_NS}/Robot",
      mesh_prim_paths=[
         "/World/Ground",
+         MultiMeshRayCasterCfg.RaycastTargetCfg(target_prim_expr="{ENV_REGEX_NS}/Robot/LF_.*/visuals"),
+         MultiMeshRayCasterCfg.RaycastTargetCfg(target_prim_expr="{ENV_REGEX_NS}/Robot/RF_.*/visuals"),
+         MultiMeshRayCasterCfg.RaycastTargetCfg(target_prim_expr="{ENV_REGEX_NS}/Robot/LH_.*/visuals"),
+         MultiMeshRayCasterCfg.RaycastTargetCfg(target_prim_expr="{ENV_REGEX_NS}/Robot/RH_.*/visuals"),
+         MultiMeshRayCasterCfg.RaycastTargetCfg(target_prim_expr="{ENV_REGEX_NS}/Robot/base/visuals"),
      ],
      pattern_cfg=patterns.GridPatternCfg(resolution=resolution, size=(5.0, 5.0)),
 )

Benchmarking & Validation

To benchmark the new raycaster, run:

python scripts/benchmarks/benchmark_ray_caster.py

Then plot the results with:

python scripts/benchmarks/plot_raycast_results.py

This will generate outputs under:
outputs/benchmarks/raycast_benchmark...

Example plots

big image
left image right image
bottom image

Type of Change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Checklist

  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

pascal-roth and others added 30 commits August 9, 2025 08:27
Add the efficient multi-mesh raycasting function implemented in Orbit.
Moreover, this PR fixes the test of it.

The new raycaster allows to raycast against multiple objects, which can
be located at different positions in each environment. The positions can
be tracked over time if enabled in the config.

- New feature (non-breaking change which adds functionality)

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Co-authored-by: zrene <[email protected]>
…ssion (isaac-sim#48)

Fixes number of meshes in the `RayCaster` when raycasting dynamically
against a regex expression of multiple objects in the scene.

- Bug fix (non-breaking change which fixes an issue)

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
Change Mulit-mesh raycaster and raycaster camera to own files, restore
the ones of main to simplify the merge.

NOTE: test of the camera is currently failing, similar as on public main
at that time, should be fixed after update to latest main

- Breaking change (fix or feature that would cause existing
functionality to not work as expected)

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [ ] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
…d fixes tests (isaac-sim#65)

ClassVar not correctly destroyed, thus removing it (follow changes of
original RayCaster). Fixing tests to comply with changes of our internal
code with 1.4.1.

- Bug fix (non-breaking change which fixes an issue)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Co-authored-by: zrene <[email protected]>
…nstances to benchmark. Fix callback issues for mulit mesh
@pavelacamposp
Copy link

Thanks for this feature! I've noticed that the duplicate mesh detection in MultiMeshRayCaster._initialize_warp_meshes() (from multi_mesh_ray_caster.py) doesn't scale well with the number of meshes.

Currently, _registered_points_idx() iterates over all registered meshes and compares their vertices. This operation is roughly O(n * V) for each new mesh (n = number of registered meshes, V = vertex count), leading to an overall O(n² * V) cost during initialization as the list of registered meshes grows (loaded_vertices).

A more efficient alternative could be to use a hash-based lookup table to detect mesh duplicates. We can assign a hash key to each mesh based on its vertices and use it for fast duplicate checks. This would reduce the overall complexity to O(n * V) for the entire duplicate mesh detection process.

Example implementation:

def _get_mesh_key(vertices: np.ndarray) -> tuple[int, int, bytes]:
    """Build a key from the shape and data hash of a mesh vertex array."""
    data = np.ascontiguousarray(vertices).view(np.uint8)  # Ensure array is contiguous
    h = hashlib.blake2b(data, digest_size=16)
    return (vertices.shape[0], vertices.shape[1], h.digest())

And in _initialize_warp_meshes():

def _initialize_warp_meshes(self):
    ...
    for target_cfg in self._raycast_targets_cfg:
        ...
        registered_meshes: dict[tuple[int, int, bytes], int] = {}  # Maps mesh keys to wp_mesh indices 
        wp_mesh_ids = []

        for target_prim in target_prims:
        	...
            if str(target_prim.GetPath()) in MultiMeshRayCaster.meshes:
                wp_mesh_ids.append(MultiMeshRayCaster.meshes[str(target_prim.GetPath())].id)
                continue
            ...
            mesh_key = _get_mesh_key(trimesh_mesh.vertices)
            registered_idx = registered_meshes.get(mesh_key, -1)
            if registered_idx != -1 and self.cfg.reference_meshes:
                omni.log.info("Found a duplicate mesh, only reference the mesh.")
                wp_mesh_ids.append(wp_mesh_ids[registered_idx])
            else:
                wp_mesh = convert_to_warp_mesh(trimesh_mesh.vertices, trimesh_mesh.faces, device=self.device)
                MultiMeshRayCaster.meshes[str(target_prim.GetPath())] = wp_mesh
                wp_mesh_ids.append(wp_mesh.id)
                registered_meshes[mesh_key] = len(wp_mesh_ids) - 1  # Store wp_mesh idx

This approach should reduce initialization time significantly when processing multiple meshes (from O(n² * V) to O(n * V)).

@renezurbruegg
Copy link
Collaborator Author

Thanks a lot for the valuable feedback. Hashing the vertices is a great idea to speed up retrieval. I’ll incorporate this, along with an additional check for potential hash collisions, once I find the time.

Also, note that cache lookups can be further accelerated by setting the is_shared flag in the configuration to true. This assumes that all environments share the same meshes, avoiding redundant checking for each one.

@Mayankm96
Copy link
Contributor

This is definitely useful feedback @pavelacamposp

@renezurbruegg I suggest though that we keep this MR to the current limitation and make a separate one with the hashing implementation. Just to not have this MR hanging around for too long :)

@renezurbruegg
Copy link
Collaborator Author

def create_primitive_mesh(prim) -> trimesh.Trimesh:
    prim_type = prim.GetTypeName()
    if prim_type == "Cube":
        size = UsdGeom.Cube(prim).GetSizeAttr().Get()
        return trimesh.creation.box(extents=(size, size, size))
    elif prim_type == "Sphere":
        r = UsdGeom.Sphere(prim).GetRadiusAttr().Get()
        return trimesh.creation.icosphere(subdivisions=3, radius=r)
    elif prim_type == "Cylinder":
        c = UsdGeom.Cylinder(prim)
        return trimesh.creation.cylinder(radius=c.GetRadiusAttr().Get(), height=c.GetHeightAttr().Get())
    elif prim_type == "Capsule":
        c = UsdGeom.Capsule(prim)
        tri_mesh = trimesh.creation.capsule(radius=c.GetRadiusAttr().Get(), height=c.GetHeightAttr().Get())
        if c.GetAxisAttr().Get() == "X":
            # rotate −90° about Y to point the length along +X
            R = rotation_matrix(np.radians(-90), [0, 1, 0])
            tri_mesh.apply_transform(R)
        elif c.GetAxisAttr().Get() == "Y":
            # rotate +90° about X to point the length along +Y
            R = rotation_matrix(np.radians(90), [1, 0, 0])
            tri_mesh.apply_transform(R)
        return tri_mesh

    elif prim_type == "Cone":
        c = UsdGeom.Cone(prim)
        radius = c.GetRadiusAttr().Get()
        height = c.GetHeightAttr().Get()
        mesh = trimesh.creation.cone(radius=radius, height=height)
        # shift all vertices down by height/2 for usd / trimesh cone primitive definiton discrepancy
        mesh.apply_translation((0.0, 0.0, -height / 2.0))
        return mesh
    else:
        raise KeyError(f"{prim_type} is not a valid primitive mesh type")

@renezurbruegg @pascal-roth I also have something in my other code to do primitive to trimesh conversion, I see currently only Plane, Cube, Sphere for ray-caster, could you please add the Cone, Capsule, Cylinder as well? Be careful with the descrepancy how trimesh cone and capsule convention might be a bit different from that of USD. I have written out the convention conversion in the code snippet above and tested it worked

if you find this single function nice, I'd also just replace all collapse helpfer functions and constant to just single function.

in my dexsuite environments, this code is also used, https://github.com/isaac-sim/IsaacLab/blob/main/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/dexsuite/mdp/utils.py

once you guys are done here, I will refactor my dexsuite environment to use your guys utility : )))

Thanks a lot for the input. I added all prim types now and verified that they work correctly:
image

@renezurbruegg
Copy link
Collaborator Author

I also see that I have a same triangulate face utility https://github.com/isaac-sim/IsaacLab/blob/main/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/dexsuite/mdp/utils.py

def _triangulate_faces(prim) -> np.ndarray:
    mesh = UsdGeom.Mesh(prim)
    counts = mesh.GetFaceVertexCountsAttr().Get()
    indices = mesh.GetFaceVertexIndicesAttr().Get()
    faces = []
    it = iter(indices)
    for cnt in counts:
        poly = [next(it) for _ in range(cnt)]
        for k in range(1, cnt - 1):
            faces.append([poly[0], poly[k], poly[k + 1]])
    return np.asarray(faces, dtype=np.int64)

your:

def convert_faces_to_triangles(faces: np.ndarray, point_counts: np.ndarray) -> np.ndarray:
    # check if the mesh is already triangulated
    if (point_counts == 3).all():
        return faces.reshape(-1, 3)  # already triangulated
    all_faces = []

    vertex_counter = 0
    # Iterates over all triangles of the mesh.
    # could be very slow for large meshes
    for num_points in point_counts:
        if num_points == 3:
            # triangle
            all_faces.append(faces[vertex_counter : vertex_counter + 3])
        elif num_points == 4:
            # quads. Subdivide into two triangles
            f = faces[vertex_counter : vertex_counter + 4]
            first_triangle = f[:3]
            second_triangle = np.array([f[0], f[2], f[3]])
            all_faces.append(first_triangle)
            all_faces.append(second_triangle)
        else:
            raise RuntimeError(f"Invalid number of points per face: {num_points}")

        vertex_counter += num_points
    return np.asarray(all_faces)

I wonder maybe you want the code still to work beyond num_points > 4?

Thanks, Updated it with your generic fan triangulation

@Mayankm96 Mayankm96 moved this to In review in Isaac Lab Oct 14, 2025
@Mayankm96
Copy link
Contributor

@renezurbruegg @pascal-roth Should we review this again and then prepare it for merge?

@renezurbruegg
Copy link
Collaborator Author

@renezurbruegg @pascal-roth Should we review this again and then prepare it for merge?

Yes 👍

There is one remaining comment from @ooctipus, which ideally would be resolved in this pr #3371

@pascal-roth
Copy link
Collaborator

@renezurbruegg we should probably do a quick profiling with tools like Nsight Systems or with Warp's ScopedTimer (https://nvidia.github.io/warp/profiling.html) to know our bottleneck for large resolutions, then we can also think about improving our kernel (maybe also for a next version)

Mayankm96 added a commit that referenced this pull request Oct 17, 2025
# Description

This MR adds two functions to obtain the pose and scale of a prim
respectively.

This is needed for #3298.

## Type of change

- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Signed-off-by: Mayank Mittal <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Kelly Guo <[email protected]>
@ooctipus
Copy link
Collaborator

ooctipus commented Oct 20, 2025

line 166 in source/isaaclab/isaaclab/sensors/ray_caster/multi_mesh_ray_caster_camera.py

if not target_cfg.is_global:

But I don't see is_global defined in target_cfg?

it should be changed to

target_cfg.track_mesh_transforms

am I right?

@Mayankm96
Copy link
Contributor

@greptileai

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Overview

Greptile Summary

This PR introduces MultiMeshRayCaster and MultiMeshRayCasterCamera to enable raycasting against multiple dynamic meshes. The key architectural changes include:

  1. New sensor classes - MultiMeshRayCaster and MultiMeshRayCasterCamera extend the base RayCaster/RayCasterCamera with support for tracking moving mesh transforms (robot parts, articulated bodies).

  2. Core infrastructure - Refactors RayCaster to use class-level mesh caching, adds low-level warp kernels (raycast_static_meshes_kernel, raycast_dynamic_meshes_kernel), and introduces mesh utility functions for USD-to-trimesh conversion.

  3. Configuration API - New MultiMeshRayCasterCfg.RaycastTargetCfg allows per-mesh configuration of tracking behavior, sharing, and merging options. The API maintains backward compatibility by converting strings to default configurations.

  4. Memory optimization - Implements mesh deduplication across environments to reduce memory footprint.

The refactoring moves mesh storage from instance to class level and extracts pose computation logic into reusable utilities (sim_utils.obtain_world_pose_from_view()), enabling dynamic mesh tracking while maintaining API compatibility.


Critical Issues Requiring Attention:

  1. Race condition in warp kernels (kernels.py lines 135-155, 221-242): Multiple threads may simultaneously check if mesh_query_ray_t.t < ray_distance[tid_env, tid_ray] and write results non-atomically. This could lead to non-deterministic hit results when multiple meshes intersect the same ray. Consider using atomic operations or mesh-ordered processing.

  2. Test failures likely (test_multi_mesh_ray_caster_camera.py lines 438, 534): Prim path mismatches where camera config references "/World/Camera" but the prim is created at "/World/Camera_warp". These tests will fail at runtime.

  3. Gymnasium major version bump (extension.toml line 20): Upgrading from 0.29.0 to 1.2.0 is a breaking change unrelated to the raycaster feature. This should be split into a separate PR to avoid introducing unexpected API breakage.

  4. Shared state pollution risk (multi_mesh_ray_caster.py line 76): Class-level mesh_offsets dict is mutable and shared across all instances. If different instances use the same prim path with different configurations, they may overwrite each other's data.

  5. Device mismatch bug (test_multi_mesh_ray_caster.py line 197): cube_rotation tensor created without device specification will default to CPU, causing device mismatch errors when used with GPU tensors.

  6. Documentation error (multi_mesh_ray_caster_cfg.py line 58): References non-existent is_global attribute instead of is_shared, misleading users about the API.


Confidence: 2/5 - Multiple critical bugs (race conditions, test failures, device mismatches) and the unrelated Gymnasium version change significantly increase merge risk.

23 files reviewed, 16 comments

Edit Code Review Agent Settings | Greptile

"toml",
"hidapi",
"gymnasium==0.29.0",
"gymnasium==1.2.0",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Major version bump from gymnasium 0.29.0to 1.2.0 - this is a breaking change in the API. The Gymnasium 1.x release introduced significant API changes including removal of deprecated features and changes to environment initialization. Have all existing environments and RL training scripts been tested with Gymnasium 1.2.0 to ensure compatibility?

Comment on lines +9 to +12
from .multi_mesh_ray_caster import MultiMeshRayCaster
from .multi_mesh_ray_caster_camera import MultiMeshRayCasterCamera
from .multi_mesh_ray_caster_camera_cfg import MultiMeshRayCasterCameraCfg
from .multi_mesh_ray_caster_cfg import MultiMeshRayCasterCfg
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: missing data class imports for the multi-mesh ray caster (e.g., MultiMeshRayCasterData, MultiMeshRayCasterCameraData). Are the data classes for MultiMeshRayCaster intentionally excluded from this module's public API, or should they be exported?

)
prim_utils.create_prim("/World/Camera_warp", "Xform")
camera_cfg_warp = MultiMeshRayCasterCameraCfg(
prim_path="/World/Camera",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: prim_path mismatch: camera_warp uses /World/Camera but prim created at /World/Camera_warp - likely causes initialization to fail

)
prim_utils.create_prim("/World/Camera_warp", "Xform")
camera_cfg_warp = MultiMeshRayCasterCameraCfg(
prim_path="/World/Camera",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: prim_path mismatch: camera_warp uses /World/Camera but prim created at /World/Camera_warp

Comment on lines +271 to +278
if not triggered:
if countdown > 0:
countdown -= 1
continue
data = scene["ray_caster"].data.ray_hits_w.cpu().numpy() # noqa: F841
triggered = True
else:
continue
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: dead code - triggered starts as True, so this block never executes and the countdown mechanism is unreachable

ray_face_id_wp = wp.empty((1, 1), dtype=wp.int32, device=torch_device)

if return_mesh_id:
ray_mesh_id = -torch.ones((n_envs, n_rays_per_env), dtype=torch.int16, device=torch_device).contiguous()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: initializes with negative values, but the docstring (line 232) says missed hits return 0. This inconsistency could cause incorrect results.

"""
self._check_supported_data_types(cfg)
# initialize base class
MultiMeshRayCaster.__init__(self, cfg)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Only MultiMeshRayCaster.__init__ is called explicitly. If RayCasterCamera has initialization logic, it will be skipped, potentially causing incomplete setup. Should both parent class constructors be called via super() or using cooperative multiple inheritance pattern?

Comment on lines +176 to +188
self.ray_hits_w, ray_depth, ray_normal, _, ray_mesh_ids = raycast_dynamic_meshes(
self._ray_starts_w[env_ids],
self._ray_directions_w[env_ids],
mesh_ids_wp=self._mesh_ids_wp, # list with shape num_envs x num_meshes_per_env
max_dist=self.cfg.max_distance,
mesh_positions_w=self._mesh_positions_w[env_ids],
mesh_orientations_w=self._mesh_orientations_w[env_ids],
return_distance=any(
[name in self.cfg.data_types for name in ["distance_to_image_plane", "distance_to_camera"]]
),
return_normal="normals" in self.cfg.data_types,
return_mesh_id=self.cfg.update_mesh_ids,
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The raycast call uses env_ids indexing for ray data but env_ids_tensor for output buffers (lines201, 205,209, 212). This inconsistency could cause indexing mismatches if env_ids is not a tensor. Should the raycast call on line 177 use env_ids_tensor instead of env_ids for consistency?

if mesh_query_ray_t.result:

# check if hit distance is less than the current hit distance, only then update the memory
if mesh_query_ray_t.t < ray_distance[tid_env, tid_ray]:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: race condition possible - multiple meshes can hit the same ray simultaneously. if two threads update ray_distance[tid_env, tid_ray] concurrently before reading it, both may pass the check and overwrite each other's results non-deterministically. are the kernel launches configured to ensure tid_mesh_id iterations happen sequentially for each (tid_env, tid_ray) pair?

if mesh_query_ray_t.result:

# check if hit distance is less than the current hit distance, only then update the memory
if mesh_query_ray_t.t < ray_distance[tid_env, tid_ray]:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: same race condition as raycast_static_meshes_kernel line 141 - concurrent writes to ray_distance. are the kernel launches configured to ensure tid_mesh_id iterations happen sequentially for each (tid_env, tid_ray) pair?

hougantc-nvda pushed a commit to hougantc-nvda/IsaacLab that referenced this pull request Oct 22, 2025
…c-sim#3371)

# Description

This MR adds two functions to obtain the pose and scale of a prim
respectively.

This is needed for isaac-sim#3298.

## Type of change

- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Signed-off-by: Mayank Mittal <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Kelly Guo <[email protected]>
george-nehma pushed a commit to george-nehma/IsaacLab-Dreamerv3 that referenced this pull request Oct 24, 2025
)

# Description

This MR does the following:

* Adds parsing of instanced prims in
`isaaclab.sim.utils.get_all_matching_child_prims` and
`isaaclab.sim.utils.get_first_matching_child_prim`. Earlier, instanced
prims were skipped since `Usd.Prim.GetChildren` does not return
instanced prims.
* Adds parsing of instanced prims in
`isaaclab.sim.utils.make_uninstanceable` to make all prims
uninstanceable.

These are needed to parse meshes for the dynamic raycaster class in
isaac-sim#3298

## Type of change

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Signed-off-by: Mayank Mittal <[email protected]>
Co-authored-by: Kelly Guo <[email protected]>
george-nehma pushed a commit to george-nehma/IsaacLab-Dreamerv3 that referenced this pull request Oct 24, 2025
…c-sim#3371)

# Description

This MR adds two functions to obtain the pose and scale of a prim
respectively.

This is needed for isaac-sim#3298.

## Type of change

- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Signed-off-by: Mayank Mittal <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Kelly Guo <[email protected]>
hougantc-nvda pushed a commit to hougantc-nvda/IsaacLab that referenced this pull request Oct 24, 2025
…c-sim#3371)

This MR adds two functions to obtain the pose and scale of a prim
respectively.

This is needed for isaac-sim#3298.

- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Signed-off-by: Mayank Mittal <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Kelly Guo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request isaac-lab Related to Isaac Lab team

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

7 participants